package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"sysu-giep/internal/api/handlers"
	"sysu-giep/internal/api/routes"
	"sysu-giep/internal/config"
	"sysu-giep/internal/database"
	"sysu-giep/internal/service"
	"sysu-giep/pkg/auth"
	"sysu-giep/pkg/logger"

	"sysu-giep/internal/api/middleware"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// @title 中山大学研究生院校企对接平台 API
// @version 1.0.0
// @description 校企对接平台后端API文档
// @termsOfService http://swagger.io/terms/

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host localhost:8080
// @BasePath /api/v1

// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description 请输入Bearer token

func main() {
	// 加载配置
	cfg, err := config.Load("configs/config.yaml")
	if err != nil {
		fmt.Printf("加载配置失败: %v\n", err)
		os.Exit(1)
	}

	// 初始化日志
	if err := logger.Init(
		cfg.Log.Level,
		cfg.Log.Format,
		cfg.Log.Output,
		cfg.Log.FilePath,
		cfg.Log.MaxSize,
		cfg.Log.MaxAge,
		cfg.Log.MaxBackups,
	); err != nil {
		fmt.Printf("初始化日志失败: %v\n", err)
		os.Exit(1)
	}
	defer func() {
		err := logger.Sync()
		if err != nil {

		}
	}()

	logger.Info("应用启动", logger.String("name", cfg.App.Name), logger.String("version", cfg.App.Version))

	// 设置Gin模式
	gin.SetMode(cfg.App.Mode)

	// 初始化数据库
	if err := database.Init(&cfg.Database); err != nil {
		logger.Fatal("初始化数据库失败", zap.Error(err))
	}
	defer func() {
		err := database.Close()
		if err != nil {
			logger.Error(err)
		}
	}()

	// 初始化Redis
	if err := database.InitRedis(&cfg.Redis); err != nil {
		logger.Fatal("初始化Redis失败", zap.Error(err))
	}
	defer func() {
		err := database.CloseRedis()
		if err != nil {

		}
	}()

	// 初始化JWT管理器
	jwtManager := auth.NewJWTManager(
		cfg.JWT.Secret,
		time.Duration(cfg.JWT.ExpireHours)*time.Hour,
	)

	// 创建Gin引擎
	engine := gin.New()

	// 设置中间件
	engine.Use(
		middleware.RequestID(),
		middleware.Logger(),
		middleware.Recovery(),
		middleware.CORS(&cfg.CORS),
		middleware.Timeout(cfg.Server.ReadTimeout),
		middleware.RateLimit(100, time.Minute), // 每分钟100次请求限制
	)

	// 设置JWT管理器
	middleware.SetJWTManager(jwtManager)

	// 设置路由
	// 在设置路由前，装配依赖并初始化处理器
	projectService := service.NewProjectService(database.GetDB(), nil)
	applicationService := service.NewApplicationService(database.GetDB())
	notificationService := service.NewNotificationService(database.GetDB())
	adminService := service.NewAdminService(database.GetDB())
	handlers.InitProjectHandlers(projectService)
	handlers.InitApplicationHandlers(applicationService)
	handlers.InitNotificationHandlers(notificationService)
	handlers.InitAdminHandlers(adminService)
	routes.SetupRoutes(engine, cfg, jwtManager)

	// 创建HTTP服务器
	server := &http.Server{
		Addr:           fmt.Sprintf(":%d", cfg.App.Port),
		Handler:        engine,
		ReadTimeout:    cfg.Server.ReadTimeout,
		WriteTimeout:   cfg.Server.WriteTimeout,
		MaxHeaderBytes: cfg.Server.MaxHeaderBytes,
	}

	// 启动服务器
	go func() {
		logger.Info("HTTP服务器启动", logger.String("addr", server.Addr))
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			logger.Fatal("HTTP服务器启动失败", zap.Error(err))
		}
	}()

	// 等待中断信号
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	logger.Info("正在关闭服务器...")

	// 优雅关闭
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		logger.Error(err)
	}

	logger.Info("服务器已关闭")
}
